import * as actions from '../actions/index';
import utils from 'utils';

// 页面初始化数据
function getInitialState(pageInfo) {
  const { pathResource, resourceSubject } = pageInfo;

  const initialState = {
    statisticInfo: {},
    projectInfo: {},
    treeData: [],
    isEmpty: pathResource ? pathResource.isEmpty === 'true' : false,
    isExist: pathResource ? pathResource.isExist === 'true' : false,
    lastCommit: {},
    blob: null,
    // 根据是否有 resourceSubject.subject 判断是否在代码库首页，若在首页，则只返回文件主体部分
    isAtOverviewPage: !resourceSubject.subject,
    renderType: '',
    blobSize: '',
    filesViewType: 'tree', // 默认值为树视图
    resourceType: resourceSubject.subject,
    resourcePath: resourceSubject.path || '',
    currentTreeData: [],
    selectedKeys: ['root'],
    defaultExpandedKeys: ['root'],
    snippets: [], // 后端存储片段的数据结构
    submodules: null,
    blobLoading: true,
    jump_line_code: window.location.hash.match(/^#L([0-9]+)/)
      ? Number(window.location.hash.match(/^#L([0-9]+)/)[1])
      : null, // 待跳转的行号
    // 即 window.FORCE.resourceSubject.subject 的值，有 blob tree new edit 四种
    selectedType: resourceSubject.subject || '',
    filterTreeData: [],
    // 是否是在初始化树
    isInittingLeftTree: false,
    // 左侧树初始化完成
    isInitedLeftTree: false,
    // 正在请求blob
    isGettingBlob: false,
    // 是否隐藏nav
    isNavHidden: false,
    // 是否正在请求表格数据
    isLoadingTable: true,
    // 是否正在请求lastCommit
    isLoadingLastCommit: true,
    // 停止导入
    isStoppingImport: false,
    // 正在初始化
    isInittingImport: false,
    // 正在删除库
    isRemovingProject: false,
    // 保护分支信息
    protectedBranch: {},
    // 克隆方式
    cloneWay: 'HTTPS',
    // 克隆账户信息
    httpsAccount: null,
    // 是否push过
    hasPush: false,
    fileReqFailInfo: '',
    // 记录当前文件对应的大小
    blobSizeMap: {},
    // 片段
    trackMap: {},
    batchDataConfig: {},
    batchDataLoading: false,
  };

  return initialState;
}

const defaultAction = {
  type: 'doNothing',
};

export default function rootIndex(state = getInitialState(window.FORCE), action = defaultAction) {
  switch (action.type) {
    case actions.RECEIVE_STATISTIC:
      return { ...state, statisticInfo: action.data };
    case actions.UPDATE_DATA:
      return { ...state, ...action.data };
    case actions.UPDATE_SELECTED_TYPE:
      return {
        ...state,
        selectedType: action.data.selectedType,
        resourcePath: action.data.resourcePath,
        selectedKeys: action.data.selectedKeys,
        blob: null,
      };
    case actions.CHANGE_ROUTER:
      return {
        ...state,
        blobLoading: true,
        resourceType: action.data.resourceType,
        resourcePath: action.data.resourcePath || '',
      };
    case actions.RECEIVE_BLOB: {
      const blob = action.data || '';
      return { ...state, blob, blobLoading: false };
    }
    case actions.RECEIVE_RENDERTYPE:
      return {
        ...state,
        renderType: action.data.type,
        blobSize: action.data.size,
        is_lfs: action.data.is_lfs,
      };
    case actions.RECEIVE_LASTCOMMIT:
      return { ...state, lastCommit: action.data };
    case actions.RECEIVE_PATHLASTCOMMIT: {
      const newTreeData = state.currentTreeData.map((file, i) => {
        const lastCommit = action.data[i];
        file.lastCommit = lastCommit.title;
        if (!lastCommit.committed_date) {
          file.lastUpdate = '';
        } else {
          file.lastUpdate = utils.getBeautyTime(
            lastCommit.committed_date,
            window.FORCE.locale,
            'simple',
          );
        }
        file.username = (!!lastCommit.user && lastCommit.user.name) || lastCommit.author_name;
        return file;
      });
      return { ...state, currentTreeData: newTreeData };
    }
    case actions.RECEIVE_PATHLASTCOMMIT_BATCH: {
      const newTreeData = [...state.currentTreeData];
      newTreeData.forEach((file) => {
        const lastCommit =
          action.data.find((item) => {
            return file.path === item.path;
          }) || {};
        file.lastCommit = lastCommit.title || '';
        if (!lastCommit.committed_date) {
          file.lastUpdate = '';
        } else {
          file.lastUpdate = utils.getBeautyTime(
            lastCommit.committed_date,
            window.FORCE.locale,
            'simple',
          );
        }
        file.username = (!!lastCommit.user && lastCommit.user.name) || lastCommit.author_name || '';
      });
      return { ...state, currentTreeData: newTreeData };
    }
    case actions.RECEIVE_SUBMODULES:
      return { ...state, submodules: action.data };
    case actions.RECEIVE_LASTCOMMIT_USER:
      state.lastCommit.user = action.data;
      return { ...state, lastCommit: { ...state.lastCommit } };
    case actions.RECEIVE_TREEDATA: {
      return {
        ...state,
        treeData: [...action.data],
        isInitedLeftTree: true,
        isInittingLeftTree: false,
      };
    }
    case actions.RECEIVE_CURRENTTREEDATA: {
      return { ...state, currentTreeData: [...action.data], isLoadingTable: false };
    }
    case actions.RECEIVE_DEFAULTEXPANDEDKEYS:
      return { ...state, defaultExpandedKeys: [...action.data] };
    case actions.RECEIVE_SELECTEDKEYS:
      return { ...state, selectedKeys: [...action.data] };
    case actions.ADD_SNIPPET: {
      const { blob, snippets } = state;
      const { file: filePath, start_line, end_line } = action.data;
      const newSnippets = [...snippets];

      // 原始的 blob 按行分割的数组
      const blobArr = blob.replace(/\r\n/g, '\n').split('\n'); // 将 \r\n 替换为 \n

      newSnippets.push({
        file: filePath,
        start_line,
        end_line,
        content: blobArr.slice(start_line - 1, end_line).join('\n'),
      });

      return { ...state, snippets: newSnippets };
    }
    case actions.CLEAR_SNIPPET: {
      const { snippets } = state;
      const { file: filePath } = action.data;
      const newSnippets = snippets.filter((snippet) => snippet.file !== filePath);

      return { ...state, snippets: newSnippets };
    }
    case actions.RECEIVE_JUMP_LINE_CODE:
      return {
        ...state,
        jump_line_code: action.data,
      };
    case actions.UPDATE_PAGE_INFO: {
      const initialState = getInitialState(action.data);
      initialState.hasPush = state.hasPush;
      return initialState;
    }
    case actions.RECEIVE_PROTECTED_BRANCHES:
      return { ...state, protectedBranch: action.data };
    case actions.CREATE_FILE:
      return { ...state, hasPush: action.data };
    case actions.RECEIVE_HTTPS_ACCOUNT:
      return { ...state, httpsAccount: action.data };
    case actions.CHANGE_BLOB_SIZE:
      return {
        ...state,
        blobSizeMap: {
          ...action.data,
        },
      };
    case actions.RECEIVE_BATCH_DATA_PROMISE:
      return {
        ...state,
        batchDataConfig: {
          ...action.data,
        },
      };
    case actions.RECEIVE_BATCH_DATA_PROMISE_LOADING:
      return {
        ...state,
        batchDataLoading: action.data,
      };
    default:
      return state;
  }
}
